package etcdv3

import (
	"gitee.com/zawei/yggdrasil/pkg"
	"gitee.com/zawei/yggdrasil/pkg/config"
	"gitee.com/zawei/yggdrasil/pkg/config/encoder"
	"gitee.com/zawei/yggdrasil/pkg/config/encoder/hcl"
	"gitee.com/zawei/yggdrasil/pkg/config/encoder/json"
	"gitee.com/zawei/yggdrasil/pkg/config/encoder/toml"
	"gitee.com/zawei/yggdrasil/pkg/config/encoder/xml"
	"gitee.com/zawei/yggdrasil/pkg/config/encoder/yaml"
	"gitee.com/zawei/yggdrasil/pkg/config/source"
	"go.etcd.io/etcd/client/v3"
)

type etcdv3Config struct {
	Items []struct {
		Prefix      string
		StripPrefix string
		Format      string
	}
	Client clientv3.Config
}

func init() {
	cfg := &etcdv3Config{}
	if err := config.Get("config", "etcdv3").Scan(cfg); err != nil {
		panic(err)
	}

	client, err := clientv3.New(cfg.Client)
	if err != nil {
		panic(err)
	}
	sources := make([]source.Source, 0, len(cfg.Items))
	encoderMap := make(map[string]encoder.Encoder)
	for _, item := range cfg.Items {
		if item.Prefix == "" {
			item.Prefix = pkg.FrameworkName() + "/conf"
		}
		if item.Format == "" {
			item.Format = "json"
		}
		e, ok := encoderMap[item.Format]
		if !ok {
			switch item.Format {
			case "json":
				e = json.NewEncoder()
			case "yaml":
				e = yaml.NewEncoder()
			case "hcl":
				e = hcl.NewEncoder()
			case "xml":
				e = xml.NewEncoder()
			case "toml":
				e = toml.NewEncoder()
			default:
				item.Format = "json"
				if e, ok = encoderMap[item.Format]; !ok {
					e = json.NewEncoder()
				}
			}
		}
		sources = append(sources, &etcd{
			prefix:      item.Prefix,
			stripPrefix: item.StripPrefix,
			encoder:     e,
			client:      client,
		})
	}
	if err := config.Load(sources...); err != nil {
		panic(err)
	}
}
